﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using SQLite;
using Windows.Storage;
using Windows.Devices.Geolocation;
namespace JarvisProject1
{
    public class FavoriteMessage
    {
        public string UserNik { get; set; }
        public int MessageId { get; set; }
    }
    public class Rubrica
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        [MaxLength(250)]
        public string Author { get; set; }
        public string Name { get; set; }
        public string Text { get; set; }
        public string BurthData { get; set; }
        public string LastChangeData { get; set; }
        public string UserNik { get; set; }
        public int SphereVisible { get; set; }
        public int DopId { get; set; }
    }
    public class Prava
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        [MaxLength(250)]
        public string NameRole { get; set; }
    }
    public class Status
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        [MaxLength(250)]
        public string StatusName { get; set; }
    }
    public class DeistvieUsera
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        [MaxLength(250)]
        public string Deistvie { get; set; }
        public string UserNik { get; set; }
    }
    public class KeyWords
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        [MaxLength(250)]
        public string Word { get; set; }
        public int RubricaName { get; set; }
    }
    public class Comment
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        [MaxLength(250)]
        public string Author { get; set; }
        public string Text { get; set; }
        public string LastChangeData { get; set; }
        public string UserNik { get; set; }
        public int RubricaId { get; set; }
        public int DopId { get; set; }
    }
    public class Geographic
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        [MaxLength(250)]
        public string Name { get; set; }
        public int DopId { get; set; }
    }
    public class LingCore
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
    }
    public class Message
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        [MaxLength(250)]
        public string Author { get; set; }
        public string Text { get; set; }
        public string BurthData { get; set; }
        public string LastChangeData { get; set; }
        public string ActualTime { get; set; }
        public string UserNik { get; set; }
        public int RubricaId { get; set; }
        public int SphereVisible { get; set; }
        public int KolvoOzenok { get; set; }
        public float AverageRate { get; set; }
    }
    public class Usser
    {
        [PrimaryKey]
        [MaxLength(250)]
        public string NikName { get; set; }
        [MaxLength(250)]
        public string Name { get; set; }
        [MaxLength(50)]
        public string Password { get; set; }
        public int Prava { get; set; }
        public int Status { get; set; }
        public int Geograph { get; set; }
        public string Email { get; set; }
        public string BurthData { get; set; }
        public string Pol { get; set; }
    }
    class Funktions
    {
        public byte[] data = null;
        private readonly string dbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "WorkDataBase.db");
        /*public void CreateDataBase()
        {
            using (var db = new SQLiteConnection(dbPath))
            {
                db.CreateTable<Prava>();
                db.CreateTable<Status>();
                db.CreateTable<LingCore>();
                db.CreateTable<Usser>();
                db.CreateTable<DeistvieUsera>();
                db.CreateTable<Comment>();
                db.CreateTable<Rubrica>();
                db.CreateTable<KeyWords>();
                db.CreateTable<Geographic>();
                db.CreateTable<Message>();
            }
        }*/
        /* public void Test()
         {
             var prava = new PravaTest();
             prava.NameRole = "Admin";
             using (var db = new SQLiteConnection(dbPath))
             {
                 db.Insert(prava);
             }   
         }*/
        /// <summary>
        /// Проверяет ник на уникальность, в случае успеха возвращает true иначе false
        /// </summary>
        /// <param name="Nik"></param>
        /// <returns></returns>
        public bool NikIdentificator(string Nik)
        {
            string s = "";
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Select NikName from Usser where Nikname = ?", Nik);
                s = command.ExecuteScalar<string>();
            }
            if (s == null)
                return true;
            else
                return false;
        }
        /// <summary>
        /// Проверяет ник и пароль, в случае успеха возвращает true иначе false
        /// </summary>
        /// <param name="Nik"></param>
        /// <param name="Password"></param>
        /// <returns></returns>
        public bool UserIdentificator(string Nik, string Password)
        {
            string s = "";
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Select NikName from Usser where Nikname = ? and Password = ?", Nik, Password);
                s = command.ExecuteScalar<string>();
            }
            if (s == null)
                return true;
            else
                return false;
        }
        /// <summary>
        /// Принимает ни и пароль и возвращает всю информацию о пользователе
        /// </summary>
        /// <param name="Nik"></param>
        /// <param name="Password"></param>
        /// <returns></returns>
        public Usser GetUserInform(string Nik, string Password)
        {
            Usser user = new Usser();
            List<Usser> l = new List<Usser>();
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Select * from Usser where Nikname = ? and Password = ?", Nik, Password);
                l = command.ExecuteQuery<Usser>();
                user = l[0];
            }
            return user;
        }
        /// <summary>
        /// Извлекает дату из устройства и приводит ее к вормату даты в базе дынных
        /// </summary>
        /// <returns></returns>
        public string Date()
        {
            string date = DateTime.Today.ToString();
            string[] tmp = date.Split(' ');
            string[] tmp2 = tmp[0].Split('.');
            date = "";
            for (int i = 2; i > 0; i--)
                date = date + tmp2[i] + "-";
            return date = date + tmp2[0];
        }
        /// <summary>
        /// Принимает дату в привычном виде и приводит ее к виду понятному базе данных
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public string Date(string date)
        {
            string[] tmp2 = date.Split('.');
            date = "";
            for (int i = 2; i > 0; i--)
                date = date + tmp2[i] + "-";
            return date = date + tmp2[0];
        }
        /// <summary>
        /// Регистрирует нового пользователя в базе данных
        /// </summary>
        /// <param name="Name"></param>
        /// <param name="CountryName"></param>
        /// <param name="Nikname"></param>
        /// <param name="Password"></param>
        public void Registration(string Name, int CountryName, string Nikname, string Password, string Email, string BurthDate, string Pol)
        {
            int id = 0;
          //  string date = Date();
            using (var db = new SQLiteConnection(dbPath))
            {
               // var command = db.CreateCommand("Select Id from Geographic where Name = ?", CountryName);
               // id = command.ExecuteScalar<int>();
               var command = db.CreateCommand("INSERT INTO Usser (NikName, Name, Password, Geograph, Email, BurthData, Pol) VALUES (?, ?, ?, ?, ?, ?, ?)", Nikname, Name, Password, CountryName, Email, Date(BurthDate), Pol);
               command.ExecuteNonQuery();
            }
        }
        /// <summary>
        /// Создает рубрику верхнего уровня, в строку data помещается информация о рубрике
        /// </summary>
        /// <param name="NikName"></param>
        /// <param name="data"></param>
        /// <param name="RubricaName"></param>
        public void NewRubrica(string NikName, string data, string RubricaName)
        {
            string date = Date();
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Select Name from Usser where NikName = ?", NikName);
                string name = command.ExecuteScalar<string>();
                command = db.CreateCommand("INSERT INTO Rubrica (UserNik, Author, BurthData, LastChangeData, Text, Name) VALUES (?, ?, ?, ?, ?, ?)", NikName, name, date, date, data, RubricaName);
                command.ExecuteNonQuery();
            }
        }//TO DO: Отладить создание рубрики со сферой видимости
        /// <summary>
        /// Создает подрубрику. Если корневой рубрики не существует возвращает строку "ok" иначе строку с ошибкой
        /// </summary>
        /// <param name="NikName"></param>
        /// <param name="data"></param>
        /// <param name="RubricaName"></param>
        /// <param name="RootId"></param>
        /// <returns></returns>
        public string NewRubrica(string NikName, string data, string RubricaName, int RootId)
        {
            string date = Date();
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Select Name from Rubrica where Id = ?", RootId);
                string Rname = command.ExecuteScalar<string>();
                if (Rname != null)
                {
                    command = db.CreateCommand("Select Name from Usser where NikName = ?", NikName);
                    string name = command.ExecuteScalar<string>();
                    command = db.CreateCommand("INSERT INTO Rubrica (UserNik, Author, BurthData, LastChangeData, Text, Name, DopId) VALUES (?, ?, ?, ?, ?, ?, ?)", NikName, name, date, date, data, RubricaName, RootId);
                    command.ExecuteNonQuery();
                    return "ok";
                }
                else
                    return "Ошибка: Корневая рубрика не существует";                  
            }
        }
        /// <summary>
        /// Принимает ник пользователя и меняет его права на админа
        /// </summary>
        /// <param name="NikName"></param>
        public void AddAdmin(string NikName)
        {
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Update Usser set Prava = 2 where NikName = ?", NikName);
                command.ExecuteNonQuery();
            }
        }
        /// <summary>
        /// Принимает Id рубрики и возвращает лист, содержащий ее подрубрики
        /// </summary>
        /// <param name="RootId"></param>
        /// <returns></returns>
        public List<string> GetRubricaList(int RootId)
        {
            List<string> list = new List<string>();
            List<Rubrica> List = new List<Rubrica>();
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Select Name from Rubrica where DopId = ?", RootId);
                List = command.ExecuteQuery<Rubrica>();
            }
            foreach (Rubrica Obj in List)
            {
                list.Add(Obj.Name);
            }
            return list;
        }
        /// <summary>
        /// Возвращает лист строк, содержащий все рубрики верхнего уровня, т. е. те, которые не имеют родительской рубрики
        /// </summary>
        /// <returns></returns>
        public List<string> GetRubricaRoot()
        {
            List<string> list = new List<string>();
            List<Rubrica> List = new List<Rubrica>();
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Select Name from Rubrica where DopId is null");
                List = command.ExecuteQuery<Rubrica>();
            }
            foreach ( Rubrica Obj in List)
            {
                list.Add(Obj.Name);
            }
            return list;
        }
        /// <summary>
        /// Данная функция возвращает лист строк, содержащий все страны из базы данных
        /// </summary>
        /// <returns></returns>
        public List<string> GetCountryList()
        {
            List<string> list = new List<string>();
            List<Geographic> List = new List<Geographic>();
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Select Name from Geographic where DopId is null");
                List = command.ExecuteQuery<Geographic>();
            }
            foreach (Geographic Obj in List)
            {
                list.Add(Obj.Name);
            }
            return list;
        }
        /// <summary>
        /// Возвращает лист строк, содержащий список географических объектов страны, Id страны принимается как параметр
        /// </summary>
        /// <param name="CountryId"></param>
        /// <returns></returns>
        public List<string> GetCountryList(int CountryId)
        {
            List<string> list = new List<string>();
            List<Geographic> List = new List<Geographic>();
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Select Name from Geographic where DopId = ?", CountryId);
                List = command.ExecuteQuery<Geographic>();
            }
            foreach (Geographic Obj in List)
            {
                list.Add(Obj.Name);
            }
            return list;
        }
        public void Geolocation()
        {
            var geolocator = new Geolocator();
            try
            {
                var position = geolocator.GetGeopositionAsync();
            }
            catch
            {
            }

        }
        public void AddRubrica(string author, string name, string text, string burthData, string lastChangeData, string userNik, int sphereVisible, int dopId)
        {       
            var rubrica = new Rubrica();
            rubrica.Author = author;
            rubrica.Name = name;
            rubrica.Text = text;
            rubrica.BurthData = burthData;
            rubrica.LastChangeData = lastChangeData;
            rubrica.UserNik = userNik;
            rubrica.SphereVisible = sphereVisible;
            rubrica.DopId = dopId;
            using (var db = new SQLiteConnection(dbPath))
            {
                db.Insert(rubrica);
            }
        }
        /// <summary>
        /// Добавляет комментарий, принимает Ник автора, текст, и id рубрики к которой пишется комментарий
        /// </summary>
        /// <param name="Nik"></param>
        /// <param name="Data"></param>
        /// <param name="RubricaId"></param>
        public void AddCommentRubrica(string Nik, string Data, int RubricaId)
        {
            string date = Date();
            using (var db = new SQLiteConnection(dbPath))
            {
                string name = this.GetUserName(Nik);
                var command = db.CreateCommand("INSERT INTO Comment (UserNik, Author, LastChangeData, Text, RubricaId) VALUES (?, ?, ?, ?, ?)", Nik, name, date, Data, RubricaId);
                command.ExecuteNonQuery();
            }
        }
        /// <summary>
        /// Добавляет комментарий к сообщению, принмает ник автора, тект и id сообщения
        /// </summary>
        /// <param name="Nik"></param>
        /// <param name="Data"></param>
        /// <param name="MessageId"></param>
        public void AddCommentMessage(string Nik, string Data, int MessageId)
        {
            string date = Date();
            using (var db = new SQLiteConnection(dbPath))
            {
                string name = this.GetUserName(Nik);
                var command = db.CreateCommand("INSERT INTO Comment (UserNik, Author, LastChangeData, Text, MessageId) VALUES (?, ?, ?, ?, ?)", Nik, name, date, Data, MessageId);
                command.ExecuteNonQuery();
            }
        }
        /// <summary>
        /// Добавляет коммментарий к комментарию, принимает ник автора, текст и id комментария
        /// </summary>
        /// <param name="Nik"></param>
        /// <param name="Data"></param>
        /// <param name="CommentId"></param>
        public void AddCommentComment(string Nik, string Data, int CommentId)
        {
            string date = Date();
            using (var db = new SQLiteConnection(dbPath))
            {
                string name = this.GetUserName(Nik);
                var command = db.CreateCommand("INSERT INTO Comment (UserNik, Author, LastChangeData, Text, DopId) VALUES (?, ?, ?, ?, ?)", Nik, name, date, Data, CommentId);
                command.ExecuteNonQuery();
            }
        }
        /// <summary>
        /// Возвращает строку с именем пользователя, принимает его ник, если такого ника нет возвращает null
        /// </summary>
        /// <param name="Nik"></param>
        /// <returns></returns>
        public string GetUserName(string Nik)
        {
            string name = "";
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Select Name from Usser where NikName = ?", Nik);
                name = command.ExecuteScalar<string>();
            }
            return name;
        }
        /// <summary>
        /// Добавляет сообщение, принимает ник автора, тескт, id рубрики, имя сообщения и срок актуальности
        /// </summary>
        /// <param name="Nik"></param>
        /// <param name="Data"></param>
        /// <param name="RubricaId"></param>
        /// <param name="Name"></param>
        public void AddMessage(string Nik, string Data, int RubricaId, string Name, string actualtime)
        {
            string date = Date();
            using (var db = new SQLiteConnection(dbPath))
            {
                string name = this.GetUserName(Nik);
                var command = db.CreateCommand("INSERT INTO Message (UserNik, Author, BurthData, LastChangeData, Text, Name, RubricaId, ActualTime) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", Nik, name, date, date, Data, Name, RubricaId, actualtime);
                command.ExecuteNonQuery();
            }
        }
        /// <summary>
        /// Возвращает всю информацию о пользователе, принимает ник
        /// </summary>
        /// <param name="Nik"></param>
        /// <returns></returns>
        public Usser GetUserInform(string Nik)
        {
            Usser inform = new Usser();
            List<Usser> list = new List<Usser>();
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Select * from Usser where NikName = ?", Nik);
                // inform = command.ExecuteScalar<Usser>();
                list = command.ExecuteQuery<Usser>();
                inform = list[0];
                return inform;
            }

        }
        /// <summary>
        /// Удаляет пользователя из базы данных по нику
        /// </summary>
        /// <param name="Nik"></param>
        public void DeleteUser(string Nik)
        {
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Delete from Usser where NikName = ?", Nik);
                command.ExecuteNonQuery();
            }
        }
        /// <summary>
        /// Удаляет запись из любой таблицы кроме Usser по Id, в параметре TableName необходимо указать имя таблицы.
        /// Таблицы называются так же как и классы.
        /// </summary>
        /// <param name="Id"></param>
        /// <param name="TableName"></param>
        public void DeleteRow(int Id, string TableName)
        {
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Delete from " + TableName + " where Id = ?", Id);
                command.ExecuteNonQuery();
            }
        }
        /// <summary>
        /// Обновляет строковые данные в таблице Usser(пароль, имя, ник).
        /// В RowName указать изменямое поле, в data указать новое значение
        /// Аккуратнее с изменением ника, проверки на его уникальность в функции не предусмотрено.
        /// </summary>
        /// <param name="Nik"></param>
        /// <param name="RowName"></param>
        /// <param name="data"></param>
        public void UpdateUser(string Nik, string RowName, string data)
        {
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Update Usser set " + RowName + " = ? where NikName = ?", data, Nik);
                command.ExecuteNonQuery();
            }
        }
        /// <summary>
        /// Обновляет все занчения изменяемые при редактировании профиля
        /// </summary>
        /// <param name="Nik"></param>
        /// <param name="RowName"></param>
        /// <param name="data"></param>
        public void UpdateUserProfil(string Nik, string Name, string BurthData, int Geograph, string Pol, string Password)
        {
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Update Usser set Name = ?, Geograph = ?, BurthData = ?, Pol = ? where Nikname = ? and Password = ?", Name, Geograph, BurthData, Pol, Nik, Password);
                command.ExecuteNonQuery();
            }
        }
        /// <summary>
        /// Обновляет целочисленные данные таблицы Usser(права, статус, географическое положение).
        /// В RowName указать изменямое поле, в data указать новое значение.
        /// </summary>
        /// <param name="Nik"></param>
        /// <param name="RowName"></param>
        /// <param name="data"></param>
        public void UpdateUser(string Nik, string RowName, int data)
        {
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Update Usser set " + RowName + " = " + data + " where NikName = ?", Nik);
                command.ExecuteNonQuery();
            }
        }
        /// <summary>
        /// Обновляет поле Text у одной из таблиц Rubrica, Comment, Message по Id.
        /// Имя таблицы указать в TableName, новый текст в поле data.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="Id"></param>
        /// <param name="TableName"></param>
        public void UpdateText(string data, int Id, string TableName)
        {
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Update " + TableName + " set Text = " + data + " where Id = ?", Id);
                command.ExecuteNonQuery();
            }
        }
        /// <summary>
        /// Добавляет сообщение в избранное
        /// </summary>
        /// <param name="Nik"></param>
        /// <param name="MessageID"></param>
        public void AddFavoriteMessage(string Nik, int MessageID)
        {
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("INSERT INTO FavoriteMessage (UserNik, MessageId) VALUES (?, ?)", Nik, MessageID);
                command.ExecuteNonQuery();
            }
        }
        /// <summary>
        /// Принимает ник и возвращает его избранные сообщенияв интовском поле класса FavoriteMassege
        /// </summary>
        /// <param name="Nik"></param>
        /// <returns></returns>
        public List<FavoriteMessage> GetFavoriteMessage(string Nik)
        {
            List<FavoriteMessage> l = new List<FavoriteMessage>();
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Select MessageId from FavoriteMessage where UserNik = ?", Nik);
                l=command.ExecuteQuery<FavoriteMessage>();
            }
            return l;
        }
        /// <summary>
        /// Удаляет из списка избранное сообщение, айдишник которого принял
        /// </summary>
        /// <param name="MessageID"></param>
        public void DeleteFavoriteMessage(int MessageID)
        {
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Delete from FavoriteMessage where MessageId = ?", MessageID);
                command.ExecuteNonQuery();
            }
        }
        public void Test()
        {

            /*using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand(
                "INSERT INTO Product (Name) VALUES (?)", "Windows 8");
                command.ExecuteNonQuery();
            }*/
            
           // List<Rubrica> list= new List<Rubrica>();
           // int id = 1;
            using (var db = new SQLiteConnection(dbPath))
            {
                var command = db.CreateCommand("Select Name from Rubrica"); //where Id = ?", id);
                command.ExecuteNonQuery();
              //  list = command.ExecuteQuery<Rubrica>();
            }
        }
    }
}